home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / RAND / DVIEW000.LZH / ADDWALL.C next >
Encoding:
C/C++ Source or Header  |  1995-09-09  |  12.5 KB  |  538 lines

  1. #define C
  2.  
  3. #undef PROFILE
  4. #define COUNT
  5.  
  6. #include "view.h"
  7. #include "trig.h"
  8.  
  9. #ifdef __GNUC__
  10.   #include <osbind.h>
  11.   #include <memory.h>
  12. #else
  13.   #include <tos.h>
  14. #endif
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.             
  20. #define SKY_COLOR       1
  21. #define FLOOR_COLOR     2
  22. #define WALL_COLOR      3
  23. #define RED_COLOR       4
  24. #define LEDGE_COLOR     5
  25. #define ZMIN            20L  
  26.  
  27. #define UPPER_TYPE      0
  28. #define WALL_TYPE       1
  29. #define LOWER_TYPE      2
  30.  
  31. extern char hash(side *ThisSide, int wall_type);
  32. extern void ColDraw(short x, short top, short bottom, char color);
  33. extern void RowDraw(short y, short left, short right, char color);
  34.  
  35. void AddFloorUp(short lb, short b, short start, short type);
  36. void AddFloorDown(short lb, short b, short start, short type);
  37. void EndFloorUp(short lb, short b, short start, short type);
  38. void EndFloorDown(short lb, short b, short start, short type);
  39.  
  40. extern short width;
  41. extern short height;
  42.  
  43. extern short flooropt;
  44. extern short floorcol;
  45. extern short nofloor;
  46. extern short wallopt;
  47. extern short wallcol;
  48. extern short singlestep;
  49. extern short showdata;
  50.  
  51. #ifdef COUNT
  52.   extern long addfloor;
  53.   extern long addfloor_loops;
  54.  
  55.   extern long addwall;
  56.   extern long addwall_loops;
  57.  
  58.   extern long coldraw;
  59.   extern long coldraw_loops;
  60.  
  61.   extern long rowdraw;
  62.   extern long rowdraw_loops;
  63. #endif
  64.  
  65. /* These are some yucky global variables.  They should probably
  66.  * be moved into the class's member data.
  67.  */
  68. extern short WallRunCount;
  69.  
  70. /* Elements of this array indicate if a screen column is completely drawn. */
  71.  
  72. #if 0
  73. extern short     Col_Done[320];
  74. #endif
  75. extern char      Col_Done[320];    /* Slightly better for the cache */
  76.  
  77.  
  78. /* Elements of this array hold indexes into the wall_run array. */
  79.  
  80. #if 1
  81. extern short     intersections[50][320];
  82. #endif
  83.  
  84. /* The number of wall_runs visible on a particular screen column. */
  85.  
  86. #if 1
  87. extern short     int_count[320];
  88. #endif
  89.  
  90. /* MaxY & MinY are the active edge lists for the top & bottom of the screen. */
  91.  
  92. extern short     MaxY[320];
  93. extern short     MinY[320];
  94.  
  95.  
  96. /* This is the wall_run array.  It contains all of the wall_runs which
  97.  * are visible in a single frame.
  98.  */
  99.  
  100. #if 1
  101. extern wall_run  walls[8000];  /* 320*50 = 16000 */
  102. #endif
  103.  
  104. extern short walltop[320];
  105. extern short wallbottom[320];
  106.  
  107. /* The next two arrays are used for both floors and ceilings.
  108.  * Elements of this array hold indexes into the floor_run array.
  109.  */
  110.  
  111. #if 1
  112. extern floor_run floorlist[200][40];
  113. #endif
  114.  
  115. extern short floorlst[200];
  116. extern short floortex[200];
  117.  
  118. /* The number of floor_runs visible on a particular screen column. */
  119.  
  120. extern short     runcount[200];
  121.  
  122.  
  123. /* The offscreen buffer. */
  124. extern char *screenbuf;
  125.  
  126.  
  127. /* This function adds the wall_runs and floor_runs to the
  128.  * lists so that they may be drawn to the screen.  It also does
  129.  * the perspective calculations on the wall heights.
  130.  */
  131.  
  132. void AddWall(short sx1, short sx2, short Rb, short Rt, short Rfz, short Rtz)
  133. {
  134.    long sy1, sy2, sy3, sy4;
  135.    short last_top, last_bottom, last_miny, last_maxy;
  136.    short top, bottom, miny, maxy;
  137.    short x;
  138.  
  139. /* Project to determine the four y screen coordinates. */
  140.  
  141.    sy1 = (long)height / 2 + ((Rb * invdistance(Rfz)) >> 16); /* bottom left. */
  142.    sy2 = (long)height / 2 + ((Rb * invdistance(Rtz)) >> 16); /* bottom right. */
  143.    sy3 = (long)height / 2 + ((Rt * invdistance(Rtz)) >> 16); /* top right. */
  144.    sy4 = (long)height / 2 + ((Rt * invdistance(Rfz)) >> 16); /* top left. */
  145.  
  146. #ifdef COUNT
  147.    addwall++;
  148. #endif
  149.  
  150.    if (sy1 < sy4) {   /* Is this really needed? */
  151.       short tmp;
  152. #if 0
  153.       printf("F");
  154. #endif
  155.       tmp = sy1;
  156.       sy1 = sy4;
  157.       sy4 = tmp;
  158.       tmp = sy2;
  159.       sy2 = sy3;
  160.       sy3 = tmp;
  161.    }
  162.  
  163.    Wall.y1  = sy4 << 16;
  164.    Wall.y2  = sy1 << 16;
  165.    Wall.dy1 = ((sy3 - sy4) << 16) / (sx2 - sx1);
  166.    Wall.dy2 = ((sy2 - sy1) << 16) / (sx2 - sx1);
  167.  
  168.    if (sx1 < 0) {
  169.       Wall.y1 -= sx1 * Wall.dy1;
  170.       Wall.y2 -= sx1 * Wall.dy2;
  171.       sx1 = 0;
  172.    }
  173.    if (sx2 > width)
  174.       sx2 = width;
  175.  
  176.    last_maxy = MaxY[sx1];
  177.    last_bottom = MaxY[sx1];
  178.    last_top = MinY[sx1];
  179.    last_miny = MinY[sx1];
  180.  
  181. #ifdef COUNT
  182.    addwall_loops += sx2 - sx1;
  183. #endif
  184.  
  185.    for(x = sx1;x < sx2;x++) {
  186.       miny   = MinY[x];
  187.       maxy   = MaxY[x];
  188.       top    = (short)(Wall.y1 >> 16);
  189.       bottom = (short)(Wall.y2 >> 16);
  190.  
  191. #if 0
  192.       if (miny < maxy) {
  193.          if ((top < maxy) && (bottom > miny)) {
  194.             if (top < miny)
  195.                top = miny;
  196.             if (bottom > maxy)
  197.                bottom = maxy;
  198.  
  199.             if (top < bottom) {
  200.                if (!wallopt) {
  201.                   walls[WallRunCount].top = top;
  202.                   walls[WallRunCount].bottom = bottom;
  203.                   intersections[int_count[x]][x] = WallRunCount;
  204.                   int_count[x]++;
  205.                } else {
  206.                   ColDraw(x, top, bottom, (char)Wall.tex_code);
  207. #if 0
  208.                   walltop[x] = top;
  209.                   wallbottom[x] = bottom;
  210. #endif
  211.                }
  212.             }
  213.          }
  214.       }
  215.                if (Wall.type == UPPER_TYPE) {
  216.                   if (!wallcol) {
  217.                      walls[WallRunCount].tex_num = LEDGE_COLOR;
  218.                   }
  219.                   if (bottom > miny)
  220.                      MinY[x] = bottom;
  221.                } else if (Wall.type == LOWER_TYPE) {
  222.                   if (!wallcol) {
  223.                      walls[WallRunCount].tex_num = LEDGE_COLOR;
  224.                   }
  225.                   if (top < maxy)
  226.                      MaxY[x] = top;
  227.                } else if (Wall.type == WALL_TYPE) {
  228.                   if (!wallcol) {
  229.                      walls[WallRunCount].tex_num = WALL_COLOR;
  230.                   }
  231.                   if (bottom > miny)
  232.                      MinY[x] = bottom;
  233.                   if (top < maxy)
  234.                      MaxY[x] = top;
  235. #if 0
  236.             if (MaxY[x] < MinY[x])
  237.                MaxY[x] = MinY[x];
  238. #endif
  239.                }
  240. #if 0
  241.             }
  242.          }
  243.       }
  244. #endif
  245.  
  246. #endif
  247.  
  248. if (!nofloor) {
  249.       if ((Wall.type == WALL_TYPE) || (Wall.type == LOWER_TYPE))
  250. #if 1
  251.          if (bottom < maxy) {
  252. #else
  253.          if ((bottom < maxy) && (bottom > miny)) {
  254. #endif
  255.             if (bottom < last_bottom)
  256.                AddFloorUp(last_bottom, bottom, x, LOWER_TYPE);
  257.             if (maxy > last_maxy)
  258.                AddFloorDown(last_maxy, maxy, x, LOWER_TYPE);
  259.             if (bottom > last_bottom)
  260.                EndFloorDown(last_bottom, bottom, x, LOWER_TYPE);
  261.             if (maxy < last_maxy)
  262.                EndFloorUp(last_maxy, maxy, x, LOWER_TYPE);
  263.          } else if (last_bottom < last_maxy)
  264.             EndFloorUp(last_maxy, last_bottom, x, LOWER_TYPE);
  265.  
  266.       if ((Wall.type == WALL_TYPE) || (Wall.type == UPPER_TYPE))
  267. #if 1
  268.          if (top > miny) {
  269. #else
  270.          if ((top > miny) && (top < maxy)) {
  271. #endif
  272.             if (top > last_top)
  273.                AddFloorDown(last_top, top, x, UPPER_TYPE);
  274.             if (miny < last_miny)
  275.                AddFloorUp(last_miny, miny, x, UPPER_TYPE);
  276.  
  277.             if (top < last_top)
  278.                EndFloorUp(last_top, top, x, UPPER_TYPE);
  279.             if (miny > last_miny)
  280.                EndFloorDown(last_miny, miny, x, UPPER_TYPE);
  281.          } else if (last_top > last_miny)
  282.             EndFloorDown(last_miny, last_top, x, UPPER_TYPE);
  283. }
  284.  
  285.       last_top    = top;
  286.       last_miny   = miny;
  287.       last_maxy   = maxy;
  288.       last_bottom = bottom;
  289.  
  290. #if 1
  291.       if (miny < maxy) {
  292.          if ((top < maxy) && (bottom > miny)) {
  293.             if (top < miny)
  294.                top = miny;
  295.             if (bottom > maxy)
  296.                bottom = maxy;
  297.  
  298.             if (top < bottom) {
  299.                if (!wallopt) {
  300.                   walls[WallRunCount].top = top;
  301.                   walls[WallRunCount].bottom = bottom;
  302.                   intersections[int_count[x]][x] = WallRunCount;
  303.                   int_count[x]++;
  304.                } else {
  305.                   ColDraw(x, top, bottom, (char)Wall.tex_code);
  306. #if 0
  307.                   walltop[x] = top;
  308.                   wallbottom[x] = bottom;
  309. #endif
  310.                }
  311.             }
  312.          }
  313.       }
  314.                if (Wall.type == UPPER_TYPE) {
  315.                   if (!wallcol) {
  316.                      walls[WallRunCount].tex_num = LEDGE_COLOR;
  317.                   }
  318.                   if (bottom > miny)
  319.                      MinY[x] = bottom;
  320.                } else if (Wall.type == LOWER_TYPE) {
  321.                   if (!wallcol) {
  322.                      walls[WallRunCount].tex_num = LEDGE_COLOR;
  323.                   }
  324.                   if (top < maxy)
  325.                      MaxY[x] = top;
  326.                } else if (Wall.type == WALL_TYPE) {
  327.                   if (!wallcol) {
  328.                      walls[WallRunCount].tex_num = WALL_COLOR;
  329.                   }
  330.                   if (bottom > miny)
  331.                      MinY[x] = bottom;
  332.                   if (top < maxy)
  333.                      MaxY[x] = top;
  334. #if 0
  335.             if (MaxY[x] < MinY[x])
  336.                MaxY[x] = MinY[x];
  337. #endif
  338.                }
  339. #if 0
  340.             }
  341.          }
  342.       }
  343. #endif
  344.  
  345. #endif
  346.       if (!wallopt) {
  347.          if (wallcol) {
  348.             walls[WallRunCount].tex_num = Wall.tex_code;   /* Added by Johan */
  349.          }
  350.  
  351.          WallRunCount++;
  352.       }
  353.       Wall.y1 += Wall.dy1;
  354.       Wall.y2 += Wall.dy2;
  355.       
  356. #if 0
  357. if (MaxY[x] < MinY[x]) {
  358.    printf("?");
  359. }
  360. #endif
  361.    }
  362. #if 0
  363. printf("\n");
  364. #endif
  365.  
  366. if (!nofloor) {
  367.    if ((Wall.type == WALL_TYPE) || (Wall.type == LOWER_TYPE))
  368.       if (last_bottom < last_maxy)
  369.          EndFloorUp(last_maxy, last_bottom, x, LOWER_TYPE);
  370.  
  371.    if ((Wall.type == WALL_TYPE) || (Wall.type == UPPER_TYPE))
  372.       if (last_top > last_miny)
  373.          EndFloorDown(last_miny, last_top, x, UPPER_TYPE);
  374. }
  375.  
  376. #if 0
  377. if (wallopt) {
  378.    for (short x = sx1;x < sx2;x++) {
  379.       ColDraw(x, walltop[x], wallbottom[x], (char)Wall.tex_code);
  380.    }
  381. }
  382. #endif
  383. }
  384.  
  385.  
  386. /* lb > b */
  387.  
  388. void AddFloorUp(short lb, short b, short start, short type)
  389. {
  390.    short row;
  391.  
  392.    char tm = hash(0, type);
  393.  
  394.    if (b < 0)
  395.       b = 0;
  396.    if (lb > height)
  397.       lb = height;
  398.  
  399. #ifdef COUNT
  400.    addfloor++;
  401.    addfloor_loops += lb - b;
  402. #endif
  403.  
  404.    for(row = b;row < lb;row++) {
  405. if (!flooropt) {
  406.          floorlist[row][runcount[row]].start = start;
  407.          floorlist[row][runcount[row]].tex_num = tm; /* Added by Johan */
  408. } else {
  409. #if 0
  410. if (floorlst[row] != -1) {
  411.       printf("!");
  412.       RowDraw(row, start, floorlst[row], tm);
  413.       floorlst[row] = -1;
  414. } else {
  415. #endif
  416.          floorlst[row] = start;
  417. #if 0
  418.          floortex[row] = tm;
  419. #endif
  420. #if 0
  421. }
  422. #endif
  423. }
  424.    }
  425. }
  426.  
  427.  
  428. /* b > lb */
  429.  
  430. void AddFloorDown(short lb, short b, short start, short type)
  431. {
  432.    short row;
  433.  
  434.    char tm = hash(0, type);
  435.  
  436.    if (lb < 0)
  437.       lb = 0;
  438.    if (b > height)
  439.       b = height;
  440.  
  441. #ifdef COUNT
  442.    addfloor++;
  443.    addfloor_loops += b - lb;
  444. #endif
  445.  
  446.    for(row = lb;row < b;row++) {
  447. if (!flooropt) {
  448.          floorlist[row][runcount[row]].start = start;
  449.          floorlist[row][runcount[row]].tex_num = tm; /* Added by Johan */
  450. } else {
  451. #if 0
  452. if (floorlst[row] != -1) {
  453.       printf("!");
  454.       RowDraw(row, start, floorlst[row], tm);
  455.       floorlst[row] = -1;
  456. } else {
  457. #endif
  458.          floorlst[row] = start;
  459. #if 0
  460.          floortex[row] = tm;
  461. #endif
  462. #if 0
  463. }
  464. #endif
  465. }
  466.    }
  467. }
  468.  
  469.  
  470. /* b < lb */
  471.  
  472. void EndFloorUp(short lb, short b, short end, short type)
  473. {
  474.    short row;
  475.    char tm = hash(0, type);
  476.  
  477.    if (b < 0)
  478.       b = 0;
  479.    if (lb > height)
  480.       lb = height;
  481.  
  482.    for(row = b;row < lb;row++) {
  483. if (!flooropt) {
  484.       floorlist[row][runcount[row]].end = end;
  485.       runcount[row]++;
  486. } else {
  487. #if 0
  488. if (floorlst[row] != -1) {
  489. #endif
  490. #if 0
  491.       RowDraw(row, floorlst[row], end, floortex[row]);
  492. #endif
  493.       RowDraw(row, floorlst[row], end, tm);
  494. #if 0
  495.       floorlst[row] = -1;
  496. } else {
  497.       floorlst[row] = end;
  498. }
  499. #endif
  500. }
  501.    }
  502. }
  503.  
  504.  
  505. /* b > lb */
  506.  
  507. void EndFloorDown(short lb, short b, short end, short type)
  508. {
  509.    short row;
  510.    char tm = hash(0, type);
  511.  
  512.    if (lb < 0)
  513.       lb = 0;
  514.    if (b > height)
  515.       b = height;
  516.  
  517.    for(row = lb;row < b;row++) {
  518. if (!flooropt) {
  519.       floorlist[row][runcount[row]].end = end;
  520.       runcount[row]++;
  521. } else {
  522. #if 0
  523. if (floorlst[row] != -1) {
  524. #endif
  525. #if 0
  526.       RowDraw(row, floorlst[row], end, floortex[row]);
  527. #endif
  528.       RowDraw(row, floorlst[row], end, tm);
  529. #if 0
  530.       floorlst[row] = -1;
  531. } else {
  532.       floorlst[row] = end;
  533. }
  534. #endif
  535. }
  536.    }
  537. }
  538.